package com.shenhaofeng.rxcache;

import android.support.annotation.NonNull;

import com.shenhaofeng.rxcache.source.CacheSource;

import java.util.Arrays;

import rx.Observable;

/**
 * 获取或持有缓存
 * Created by haofeng on 2016/9/25.
 */

public class CacheProvider<T> {


    private CacheSource<T>[] mCacheSources;

    /**
     * 不应该直接实例化
     *
     * @param firstSource
     * @param sources
     */
    private CacheProvider(CacheSource<T> firstSource, CacheSource<T>... sources) {
        CacheSource<T>[] first = new CacheSource[]{firstSource};
        CacheSource<T>[] cacheSources = Arrays.copyOf(first, first.length + sources.length);
        System.arraycopy(sources, 0, cacheSources, first.length, sources.length);
        this.mCacheSources = cacheSources;
    }


    /**
     * 创建一个缓存数据的提供者,根据传入的顺序读取缓存
     *
     * @param firstSource 缓存源至少有一个
     * @param sources     额外的缓存源
     * @param <T>
     * @return 缓存控制器
     */
    public static <T> CacheProvider<T> from(@NonNull CacheSource<T> firstSource, CacheSource<T>... sources) {
        return new CacheProvider<>(firstSource, sources);

    }

    /**
     * 创建一个缓存数据的提供者
     *
     * @param source 缓存数据源
     * @param <T>
     * @return 缓存控制器
     */
    public static <T> CacheProvider<T> create(@NonNull CacheSource<T> source) {
        return from(source);
    }

    /**
     * 创建一个缓存数据的提供者,根据传入的顺序读取缓存
     *
     * @param source1 缓存数据源
     * @param source2 缓存数据源
     * @param <T>
     * @return 缓存控制器
     */
    public static <T> CacheProvider<T> create(@NonNull CacheSource<T> source1, CacheSource<T> source2) {
        return from(source1, source2);
    }

    /**
     * 创建一个缓存数据的提供者,根据传入的顺序读取缓存
     *
     * @param source1 缓存数据源
     * @param source2 缓存数据源
     * @param source3 缓存数据源
     * @param <T>
     * @return 缓存控制器
     */
    public static <T> CacheProvider<T> create(@NonNull CacheSource<T> source1, CacheSource<T> source2, CacheSource<T> source3) {
        return from(source1, source2, source3);
    }

    /**
     * 创建一个缓存数据的提供者,根据传入的顺序读取缓存
     *
     * @param source1 缓存数据源
     * @param source2 缓存数据源
     * @param source3 缓存数据源
     * @param source4 缓存数据源
     * @param <T>
     * @return 缓存控制器
     */
    public static <T> CacheProvider<T> create(@NonNull CacheSource<T> source1, CacheSource<T> source2, CacheSource<T> source3, CacheSource<T> source4) {
        return from(source1, source2, source3, source4);
    }

    /**
     * 创建一个多级缓存的可观察对象
     *
     * @return 缓存数据的数据源
     */
    public Observable<T> cache(String key) {
        return Observable.create(new LoadCacheOnSubscribe<>(key, mCacheSources));
    }


    /**
     * 提交缓存数据
     *
     * @param key
     * @param cache
     */
    public void put(String key, T cache) {
        for (CacheSource<T> source : mCacheSources) {
            source.put(key, cache);
        }
    }


}
